using System;
using System.Collections.Generic;
using UnityEditor.UI;

public class RedPointNode
{
    public ulong Id { get; private set; }
    public string name { get; private set; }

    private bool lastCheckResult;//节点红点检测结果

    private int SelfCount;//自身红点个数
    private int ChildCount;//孩子红点个数

    public int RedCount => SelfCount + ChildCount;//红点总数

    public RedPointNode parent; //父节点
    public Dictionary<ulong, RedPointNode> childs = new Dictionary<ulong, RedPointNode>();//子节点列表

    private Action<RedPointNode> OnRedPointStateChange;//事件 当红点个数变化，一般通知ui刷新
    private Func<int> OnRedPointCheck;//根据具体模块条件检测红点个数

    public bool isExtend;//editor 使用

    public RedPointNode(string name)
    {
        this.name = name;
    }

    /// <summary>
    /// 获取或者创建一个节点
    /// </summary>
    /// <param name="eRedPoint"></param>
    /// <returns></returns>
    public RedPointNode GetOrAddRedPointNode(ERedPoint eRedPoint)
    {
        ulong id = (ulong)eRedPoint;
        var childNode = GetOrAddRedPointNode(id);
        childNode.name = eRedPoint.ToString();
        return childNode;
    }

    /// <summary>
    /// 获取或者创建一个节点
    /// </summary>
    /// <param name="eRedPoint"></param>
    /// <returns></returns>
    public RedPointNode GetOrAddRedPointNode(ulong eRedPointId)
    {
        if (!childs.TryGetValue(eRedPointId, out RedPointNode result))
        {
            result = new RedPointNode(eRedPointId.ToString());
            result.Id = eRedPointId;
            result.parent = this;
            childs.Add(eRedPointId, result);
        }

        return result;
    }


    public void ChangeParentNum(int num)
    {
        if (parent != null)
        {
            parent.ChildCount += num;
            parent.OnRedPointStateChange?.Invoke(parent);
            parent.ChangeParentNum(num);
        }
    }

    public void RedPointCheck(bool isLeaf = false)
    {
        var result = 0;
        if (OnRedPointCheck != null)
        {
            result = OnRedPointCheck.Invoke();
        }

        if (RedCount != result)
        {
            int diff = result - RedCount;
            if (isLeaf)
            {
                SelfCount += diff;
            }
            else
            {
                ChildCount += diff;
            }

            ChangeParentNum(diff);
            OnRedPointStateChange?.Invoke(this);
        }
    }

    public void AddOnRedPointStateChangeListener(Action<RedPointNode> OnRedPointStateChange)
    {
        this.OnRedPointStateChange = OnRedPointStateChange;
        OnRedPointStateChange?.Invoke(this);
    }

    public void ClearOnRedPointStateChangeListener()
    {
        this.OnRedPointStateChange = null;
    }

    public void AddOnRedPointCheckListener(Func<int> OnRedPointCheck, bool isLeaf = false)
    {
        this.OnRedPointCheck = OnRedPointCheck;
        RedPointCheck(isLeaf);
    }

    public void ClearOnRedPointCheckListener()
    {
        this.OnRedPointCheck = null;
    }

    public void Release()
    {
        Id = 0;
        name = null;
        lastCheckResult = false;
        SelfCount = ChildCount = 0;
        parent = null;
        OnRedPointStateChange?.Invoke(this);
        OnRedPointStateChange = null;
        OnRedPointCheck = null;
    }
}